package org.dpms.config.shiro;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.dpms.entity.User;
import org.dpms.service.IUserService;

import com.alibaba.dubbo.config.annotation.Reference;

	/** 
	 *  身份校验核心类; 
	 * @author Angel(QQ:412887952) 
	 * @version v.0.1 
	 */  
	public class MyShiroRealm extends AuthorizingRealm{  
	   
	         
		@Reference(version = "1.0.0")
	    private IUserService userService;  
	     
	    /** 
	     * 认证信息.(身份验证) 
	     * : 
	     * Authentication 是用来验证用户身份 
	     * @param token 
	     * @return 
	     * @throws AuthenticationException 
	     */  
	    @Override  
	    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {  
	    	AuthenticationInfo info = null;
	    	// 将token装换成UsernamePasswordToken
	        UsernamePasswordToken upToken = (UsernamePasswordToken) token;
	        // 获取用户名即可
	        String username = upToken.getUsername();
	        // 查询数据库，是否查询到用户名和密码的用户
	         User user = userService.queryInfoByUsername(username);

	        if(user  != null) {
	            // 如果查询到了，封装查询结果，返回给我们的调用
	            Object principal =  user.getNickname();
	            Object credentials = user.getPswd();

	            // 获取盐值，即用户名
	            ByteSource salt = ByteSource.Util.bytes(username);
	            String realmName = this.getName();
	            // 将账户名，密码，盐值，realmName实例化到SimpleAuthenticationInfo中交给Shiro来管理
	            info = new SimpleAuthenticationInfo(principal, credentials, salt,realmName);
	        }else {
	            // 如果没有查询到，抛出一个异常
	        	throw new UnknownAccountException("用户名或者密码错误");
	        }
	        return info;
	    }  
	     
	     
	     
	    /** 
	     * 此方法调用  hasRole,hasPermission的时候才会进行回调. 
	     * 
	     * 权限信息.(授权): 
	     * 1、如果用户正常退出，缓存自动清空； 
	     * 2、如果用户非正常退出，缓存自动清空； 
	     * 3、如果我们修改了用户的权限，而用户不退出系统，修改的权限无法立即生效。 
	     * （需要手动编程进行实现；放在service进行调用） 
	     * 在权限修改后调用realm中的方法，realm已经由spring管理，所以从spring中获取realm实例， 
	     * 调用clearCached方法； 
	     * :Authorization 是授权访问控制，用于对用户进行的操作授权，证明该用户是否允许进行当前操作，如访问某个链接，某个资源文件等。 
	     * @param principals 
	     * @return 
	     */  
	    @Override  
	    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {  
	     return null;
	}  
}
